/*
	Copyright (C) 2012  Rick Brown

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.jgenhtml;

import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * A page generated by processing an LCOV description file.
 * Reads descriptions generated by gendesc.
 * @author Rick Brown
 */
public class DescriptionsPage
{
	private static final Logger LOGGER = Logger.getLogger(DescriptionsPage.class.getName());
	private Element descriptions;
	private Document doc;
	private Set<String> runTests;
	private boolean ignoreDescriptions;

	public DescriptionsPage(final String testName, Set<String> runTests) throws ParserConfigurationException
	{
		DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder;
		docBuilder = dbfac.newDocumentBuilder();
		this.doc = docBuilder.newDocument();
		descriptions = doc.createElement("descriptions");
		if(CoverageReport.getConfig().isKeepDescriptions())
		{
			this.runTests = null;
		}
		else
		{
			this.runTests = runTests;
		}
		this.ignoreDescriptions = false;
		this.doc.appendChild(descriptions);
		JGenHtmlUtils.setGlobalRootAttributes(descriptions, testName);
	}

	/**
	 * Add more description information.
	 * @param line a line from the description file.
	 */
	public void addLine(final String lineToAdd)
	{
		String line = lineToAdd.trim();
		String[] data = JGenHtmlUtils.extractLineValues(line);
		if(data != null && data.length > 0)
		{
			String datum = data[0].trim();
			if(line.startsWith("TN:"))
			{
				if(this.runTests == null || this.runTests.contains(datum))
				{
					ignoreDescriptions = false;
					Element description = doc.createElement("description");
					description.setAttribute("test-name", datum);
					descriptions.appendChild(description);
				}
				else
				{
					LOGGER.log(Level.FINE, "ignoring test '{}'", datum);
					ignoreDescriptions = true;
				}
			}
			else if(!ignoreDescriptions && line.startsWith("TD:"))
			{
				Element description = (Element) descriptions.getLastChild();
				Element info = doc.createElement("info");
				description.appendChild(info);
				info.setTextContent(datum);
			}
		}
	}

	/**
	 * Writes this instance to the filesystem as a report page (xml/html).
	 * @param rootDir The root output directory.
	 * @param asXml If true, will write XML files (for client side transform) instead of HTML.
	 * @throws TransformerConfigurationException
	 * @throws TransformerException
	 */
	public void writeToFileSystem(final File rootDir, final boolean asXml) throws TransformerConfigurationException, TransformerException, IOException
	{
		String tagetFileName = "descriptions";
		Config config = CoverageReport.getConfig();
		File outDir = config.isHtmlOnly()? JGenHtmlUtils.getTargetDir(rootDir, "") : JGenHtmlUtils.getTargetDir(rootDir, asXml);
		File out;
		if(asXml)
		{
			JGenHtmlUtils.linkToXsl(doc, JGenHtmlUtils.XSLT_NAME);
			out = new File(outDir, tagetFileName + ".xml");
		}
		else
		{
			out = new File(outDir, tagetFileName + config.getHtmlExt());
		}
		JGenHtmlUtils.transformToFile(out, asXml, doc);
	}
}
